package com.namecard.namecardapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.namecard.namecardapi.entity.UserInfo;
import com.namecard.namecardapi.exception.BusinessException;
import com.namecard.namecardapi.mapper.*;
import com.namecard.namecardapi.service.UserInfoService;
import com.namecard.namecardapi.entity.vo.LoginVO;
import com.namecard.namecardapi.util.Constants;
import com.namecard.namecardapi.util.FileUploadUtil;
import com.namecard.namecardapi.util.RedisUtil;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wzx
 * @since 2023-07-03
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private CardInfoMapper cardInfoMapper;

    @Resource
    private AccountInfoMapper accountInfoMapper;

    @Resource
    private ImageMapper imageMapper;

    @Resource
    private RechargeInfoMapper rechargeInfoMapper;

    @Resource
    private CardOrderInfoMapper cardOrderInfoMapper;



    @Resource
    RedisUtil redisUtil;

    private static final String AVATAR_INPUT_FALSE = "保存头像失败，请联系后台";
    private static final String AVATAR_OUTPUT_FALSE = "获取头像失败，请联系后台";
    private static final String REGISTER_FALSE = "注册失败，请联系后台";

    private static final String JPG_TYPE = ".jpg";

    private static final String PNG_TYPE = ".png";

    /**
     * 驗證用戶是否合法
     * @param loginVo
     * @return
     */
    @Override
    public Boolean islegal(LoginVO loginVo) {
        try {
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url("https://api.minepi.com/v2/me")
                    .addHeader("Authorization", "Bearer " + loginVo.getAccessToken())
                    .build();
            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    return false;
                }
                String string = response.body().string();
                JSONObject jsonObject1 = JSON.parseObject(string);
                if (!jsonObject1.getString("uid").equals(loginVo.getUserId())) {
                    return false;
                }

                UserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_id", loginVo.getUserId()));
                if (null != userInfo) {
                    //如果用户存在更新token
                    if (!userInfo.getAccessToken().equals(userInfo.getAccessToken())) {
                        userInfo.setAccessToken(userInfo.getAccessToken());
                        userInfoMapper.updateById(userInfo);

                    }
                } else {
                    //新用户
                    userInfo = new UserInfo();
                    userInfo.setUserId(loginVo.getUserId());
                    userInfo.setAccessToken(loginVo.getAccessToken());
                    userInfo.setUserName(loginVo.getUserName());

                    userInfoMapper.insert(userInfo);

                }
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public UserInfo getByIdOrUserId(Long id, String userId) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getId, id).or().eq(UserInfo::getUserId, userId);
        return this.getOne(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfo login(LoginVO loginVo) {
        String userId = loginVo.getUserName();
        // 根据pi_name查询数据库
        String userName = loginVo.getUserName();
        UserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfo>()
                .eq("user_name", userName));
        // 根据是否为空选择是否进行注册登录
        if (userInfo != null) {
            // 刷新记录当前登录的时间
            userInfoMapper.update(null, new UpdateWrapper<UserInfo>()
                    .eq("user_name", userName).set("last_login", new Date()));
            //更新token
            if (!userInfo.getAccessToken().equals(loginVo.getAccessToken())) {
                userInfo.setAccessToken(loginVo.getAccessToken());
                userInfoMapper.updateById(userInfo);
            }
            if (StringUtils.isNotBlank(userInfo.getUserImage())){
                userInfo.setUserImage(imageMapper.selectPath(userInfo.getUserImage()));
            }
            userInfo.setUserImage(userInfo.getUserImage());
            // 已注册
            return userInfo;
        }
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://api.minepi.com/v2/me")
                .addHeader("Authorization", "Bearer " + loginVo.getAccessToken())
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                return null;
            }
            String string = response.body().string();
            JSONObject jsonObject1 = JSON.parseObject(string);

            if (!jsonObject1.getString("username").equals(userName)) {
                return null;
            }

            //新用户
            UserInfo newUser = new UserInfo();
            // 属性转移
            newUser.setUserName(userName);
            newUser.setAccessToken(loginVo.getAccessToken());
            newUser.setUserId(userId);
            // 插入数据
            int insert = userInfoMapper.insert(newUser);
            //创建用户账号
            insert += accountInfoMapper.createAccount(userId);//userId = userName


            if (insert < 2){throw new BusinessException(REGISTER_FALSE);}

            // 获取最新的注册后的用户数据（包含默认值）
            return userInfoMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_id", userId));

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfo tocysLogin(LoginVO loginVo) {

        String userId = loginVo.getUserName();
        // 根据pi_name查询数据库
        String userName = loginVo.getUserName();
        UserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfo>()
                .eq("user_name", userName));
        // 根据是否为空选择是否进行注册登录
        if (userInfo != null) {
            // 刷新记录当前登录的时间
            userInfoMapper.update(null, new UpdateWrapper<UserInfo>()
                    .eq("user_name", userName).set("last_login", new Date()));
            //更新token
            if (!userInfo.getAccessToken().equals(loginVo.getAccessToken())) {
                userInfo.setAccessToken(loginVo.getAccessToken());
                userInfoMapper.updateById(userInfo);
            }
            if (StringUtils.isNotBlank(userInfo.getUserImage())){
                userInfo.setUserImage(imageMapper.selectPath(userInfo.getUserImage()));
            }
            userInfo.setUserImage(userInfo.getUserImage());
            // 已注册
            return userInfo;
        }
            //新用户
            UserInfo newUser = new UserInfo();
            // 属性转移
            newUser.setUserName(userName);
            newUser.setAccessToken(loginVo.getAccessToken());
            newUser.setUserId(userId);
            // 插入数据
            int insert = userInfoMapper.insert(newUser);
            //创建用户账号
            insert += accountInfoMapper.createAccount(userId);

            if (insert < 2){throw new BusinessException(REGISTER_FALSE);}

            // 获取最新的注册后的用户数据（包含默认值）
            return userInfoMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_id", userId));
    }

    @Override
    public void updateName(String userName,String userId) {
        // 更新用户名字
        userInfoMapper.update(null, new UpdateWrapper<UserInfo>()
                                            .eq("user_id", userId)
                                            .set("user_name", userName));

    }

    @Override
    public void updatePersonalProfile(String personalProfile, String userId) {
        //更新用户个人简介
        userInfoMapper.update(null,new UpdateWrapper<UserInfo>()
                .eq("user_id",userId)
                .set("personal_profile",personalProfile));
    }

    @Override
    public void updateColour(Integer colourId, String userId) {
        //更新用户个人主题颜色
        userInfoMapper.update(null,new UpdateWrapper<UserInfo>()
                .eq("user_id",userId)
                .set("colour",colourId));

    }

    @Override
    public void getRedisPushData() {
        // 查询名片库总数据
        List<String> cardIds = userInfoMapper.getRedisPushData(0, Constants.REDIS_DATA_SUM);
        // 查询数据库拿300条数据封装起来（划分为3份）
        List<String> cardIds1 = userInfoMapper.getRedisPushData(0, Constants.REDIS_DATA_SUM / 3);
        // 将数据存入到redis中
        redisUtil.saveListToRedis("baseBucket_1", cardIds1, Constants.REDIS_DATA_VALID_TIME);
    }

    @Override
    public String saveAvatar(String userId, MultipartFile imageFile) {
        List<String> sizeList = new ArrayList<>();
        sizeList.add(Constants.USER_IMAGE_SIZE_SMALL);
        String imageId = FileUploadUtil.allUploadImageData(imageFile, imageMapper, FileUploadUtil.AVATAR,sizeList);
        // 外键关联目标图片数据
        int update = userInfoMapper.update(null, new LambdaUpdateWrapper<UserInfo>()
                .eq(UserInfo::getUserId, userId)
                .set(UserInfo::getUserImage, imageId));
        if (update < 1) {
            log.error("外键关联目标图片数据");
            return null;
        }
        UserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfo>()
                .eq("user_id", userId)
                .select("user_image"));
        return imageMapper.selectPath(userInfo.getUserImage());
    }

    @Override
    public String getAvatar(String userId) {
        try {
            UserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfo>()
                    .eq("user_id", userId)
                    .select("user_image"));
            return imageMapper.selectPath(userInfo.getUserImage());
        } catch (Exception e) {
            throw new BusinessException(AVATAR_OUTPUT_FALSE);
        }
    }


}
